﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace KalamburyCanvas
{
    public partial class KalamburyCanvasControl : UserControl
    {
        public delegate void NewImageEventHandler(object sender, KalamburyControlEventArg e);
        public event NewImageEventHandler NewImage;

        Graphics g;
        Point p = Point.Empty;
        Pen pen;
        private bool _onlyView = true;
        public bool OnlyView
        {
            get
            {
                return _onlyView;
            }
            set
            {
                if (_onlyView == true)
                {
                    g = Graphics.FromImage(pictureBox.Image);       
                }
                _onlyView = value;
                if (value == true)
                    pictureBox.Cursor = Cursors.No;
                else
                    pictureBox.Cursor = Cursors.Cross;
            }
        }
        private string BinaryImage = null;

        public KalamburyCanvasControl()
        {
            InitializeComponent();
            pictureBox.Image = new Bitmap(pictureBox.Width, pictureBox.Height);
            g = Graphics.FromImage(pictureBox.Image);
            pen = new Pen(Color.White);
        }

        private void pictureBox_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left && !_onlyView)
                p = e.Location;
        }

        private void pictureBox_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left && !_onlyView)
            {
                g.DrawLine(pen, p, e.Location);
                p = e.Location;
                try
                {
                    pictureBox.Refresh();
                }
                catch (System.StackOverflowException)
                { }
                catch (Exception)
                {}
                Application.DoEvents();
            }
        }

        private void pictureBox_MouseUp(object sender, MouseEventArgs e)
        {
            if (!_onlyView)
                ToBinary();
        }

        public void Clear()
        {
            pictureBox.Image = new Bitmap(pictureBox.Width, pictureBox.Height);
            pictureBox.Invalidate();
            g = Graphics.FromImage(pictureBox.Image);
        }

        private void ToBinary()
        {
            MemoryStream memStrem = new MemoryStream();
            try
            {
                BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(memStrem, pictureBox.Image);
                BinaryImage = Convert.ToBase64String(memStrem.ToArray());
            }
            finally
            {
                memStrem.Close();
                memStrem.Dispose();
            }
            if (NewImage != null)
                NewImage(this, new KalamburyControlEventArg(BinaryImage));
            //TODO
        }

        public void PutImage(string ImageInString)
        {
            if (!_onlyView)
                return;
            BinaryFormatter bf = new BinaryFormatter();
            byte[] imageBytes = Convert.FromBase64String(ImageInString);
            using (MemoryStream ms = new MemoryStream(imageBytes)){
                try
                {
                    pictureBox.Image = bf.Deserialize(ms) as Image;
                }
                catch (ArgumentException)
                {
                    throw;
                }
                    //.Image.Image.FromStream(ms);
            }
            Application.DoEvents();
        }


    }
    public class KalamburyControlEventArg : EventArgs
    {
        public string ImageInString { get; private set; }

        public KalamburyControlEventArg(string ImageInString)
        {
            this.ImageInString = ImageInString;
        }
    }
}
